package com.sdkj.controller.activiti;

import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.sdkj.activiti.util.ActivitiUtils;
import com.sdkj.controller.base.BaseController;
import com.sdkj.entity.Activiti;
import com.sdkj.entity.Page;
import com.sdkj.service.activiti.ActTaskService;
import com.sdkj.service.car.CarApplyService;
import com.sdkj.service.materials.getmaterials.ApplyGetMaterialsService;
import com.sdkj.util.Const;
import com.sdkj.util.PageData;

/**
 * 流程个人任务相关Controller
 * @author leiweiping
 * @version 2013-11-03
 */
@Controller
@RequestMapping(value = "acttask")
public class ActTaskController extends BaseController {

	@Resource
	private ActTaskService actTaskService;
	
	@Resource
	private CarApplyService carapplyService;
	@Resource
	ApplyGetMaterialsService applygetmaterialsService;
	/**
	 * 获取待办列表
	 * @param procDefKey 流程定义标识
	 * @return
	 */
	@RequestMapping(value = "/todo")
	public ModelAndView todoList(Page page) throws Exception {
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		pd = this.getPageData();
		pd.put("user_id", getCurrentUser().getUSER_ID());
		List<Activiti> varList = actTaskService.todoList(pd);
		mv.setViewName("activiti/task/task_todo_list");
		mv.addObject("varList", varList);
		mv.addObject("pd", pd);
		mv.addObject(Const.SESSION_QX,this.getHC());	//按钮权限
		return mv;
	}
	
	/**
	 * 获取已办任务
	 * @param page
	 * @param procDefKey 流程定义标识
	 * @return
	 */
	@RequestMapping(value = "/historic")
	public ModelAndView historicList(Page page) throws Exception {
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		pd = this.getPageData();
		pd.put("user_id", getCurrentUser().getUSER_ID());
		List<Activiti> varList = actTaskService.historicList(pd);
		mv.setViewName("activiti/task/task_historic_list");
		mv.addObject("varList", varList);
		mv.addObject("pd", pd);
		mv.addObject(Const.SESSION_QX,this.getHC());	//按钮权限
		return mv;
	}

	/**
	 * 获取流转历史列表
	 * @param procInsId 流程实例
	 * @param startAct 开始活动节点名称
	 * @param endAct 结束活动节点名称
	 */
	@RequestMapping(value = "histoicFlow")
	public ModelAndView histoicFlow(Page page){
		ModelAndView mv = this.getModelAndView();
		try {
			PageData pd = new PageData();
			pd = this.getPageData();
			List<Activiti> varList = actTaskService.histoicFlowList(pd);
			mv.setViewName("activiti/task/task_historic_flow");
			mv.addObject("varList", varList);
			mv.addObject("pd", pd);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mv.addObject(Const.SESSION_QX,this.getHC());	//按钮权限
		return mv;
	}
	
	/**
	 * 获取流程列表
	 * @param category 流程分类
	 */
	@RequestMapping(value = "/process")
	public ModelAndView processList(Page page) {
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		pd = this.getPageData();
		List<Object[]> varList = actTaskService.processList(pd);
		mv.setViewName("activiti/process/process_list");
		mv.addObject("varList", varList);
		mv.addObject("pd", pd);
		mv.addObject(Const.SESSION_QX,this.getHC());	//按钮权限
		return mv;
	}
	
	/**
	 * 获取流程表单
	 * @param taskId	任务ID
	 * @param taskName	任务名称
	 * @param taskDefKey 任务环节标识
	 * @param procInsId 流程实例ID
	 * @param procDefId 流程定义ID
	 */
	@RequestMapping(value = "/form")
	public ModelAndView form(Activiti act, HttpServletRequest request){
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		// 获取流程XML上的表单KEY
		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
		System.out.println("XXXXXXX====formKey="+formKey);
		try {
			//车辆审核
			if("carapply".equals(formKey)||formKey == "carapply"){
				pd.put("process_instance_id", act.getProcInsId());
				pd = carapplyService.findByProcInsId(pd);
				//流程实例ID
				pd.put("procInsId", act.getProcInsId());
				pd.put("user_id", getCurrentUser().getUSER_ID());
				List<Activiti> varList = actTaskService.histoicFlowList(pd);
				
				// 获取流程实例对象
				if (act.getProcInsId() != null){
					act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
				}
				
				mv.setViewName("car/carapply/carapply_form");
				mv.addObject("act", act);
				mv.addObject("varList", varList);
				mv.addObject("pd", pd);
			}
			
			//物资申请审核
			if("applygetmaterials".equals(formKey)){
				System.out.println("XXXXXXX====2222");
				pd.put("process_instance_id", act.getProcInsId());
				HashMap<String,Object> map=applygetmaterialsService.findObjById(pd);//获取信息
				PageData pdApply=(PageData)map.get("pdApply");
				List<PageData> detailList =(List<PageData>)map.get("detailList");
				//流程实例ID
				pd.put("procInsId", act.getProcInsId());
				pd.put("user_id", getCurrentUser().getUSER_ID());
				List<Activiti> varList = actTaskService.histoicFlowList(pd);
				// 获取流程实例对象
				if (act.getProcInsId() != null){
					act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
				}
				mv.setViewName("materials/getmaterials/applygetmaterials_form");
				mv.addObject("act", act);
				mv.addObject("varList", varList);
				mv.addObject("pd", pdApply);
				mv.addObject("detailList", detailList);
				mv.addObject("msg", "approve");//审批的controller
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}
	
	/**
	 * 获取流程表单
	 * @param taskId	任务ID
	 * @param taskName	任务名称
	 * @param taskDefKey 任务环节标识
	 * @param procInsId 流程实例ID
	 * @param procDefId 流程定义ID
	 */
	@RequestMapping(value = "/goForm")
	public ModelAndView goForm(Activiti act, HttpServletRequest request){
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		// 获取流程XML上的表单KEY
		String formKey = actTaskService.getFormKey(act.getProcDefId(), act.getTaskDefKey());
		try {
			
			for (String key : ActivitiUtils.activitiMap.keySet()) {
				if(key.equals(formKey)){
					String[] arr=ActivitiUtils.activitiMap.get(key);
					String formUrl=arr[2];
					pd.put("process_instance_id", act.getProcInsId());
					pd = carapplyService.findByProcInsId(pd);
					//流程实例ID
					pd.put("procInsId", act.getProcInsId());
					pd.put("user_id", getCurrentUser().getUSER_ID());
					List<Activiti> varList = actTaskService.histoicFlowList(pd);
					// 获取流程实例对象
					if (act.getProcInsId() != null){
						act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
					}
					mv.setViewName(formUrl);
					mv.addObject("act", act);
					mv.addObject("varList", varList);
					mv.addObject("pd", pd);
				}
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}
	
	
	/**
	 * 启动流程
	 * @param procDefKey 流程定义KEY
	 * @param businessTable 业务表表名
	 * @param businessId	业务表编号
	 */
	@RequestMapping(value = "start")
	@ResponseBody
	public String start() throws Exception {
		PageData pd = new PageData();
		pd = this.getPageData();
		String procDefKey = pd.getString("procDefKey");
		String businessId = pd.getString("businessId");
		String businessTable = pd.getString("businessTable");
		String title = pd.getString("title");
		actTaskService.startProcess(procDefKey, businessId, businessTable, title);
		return "true";
	}

	/**
	 * 签收任务
	 * @param taskId 任务ID
	 */
	@RequestMapping(value = "claim")
	@ResponseBody
	public String claim(Activiti act) {
		String userId = getCurrentUser().getUSER_ID();
		actTaskService.claim(act.getTaskId(), userId);
		return "true";
	}
	
	/**
	 * 完成任务
	 * @param taskId 任务ID
	 * @param procInsId 流程实例ID，如果为空，则不保存任务提交意见
	 * @param comment 任务提交意见的内容
	 * @param vars 任务流程变量，如下
	 * 		vars.keys=flag,pass
	 * 		vars.values=1,true
	 * 		vars.types=S,B  @see com.thinkgem.jeesite.modules.act.utils.PropertyType
	 */
	@RequestMapping(value = "complete")
	@ResponseBody
	public String complete(Activiti act) {
		actTaskService.complete(act.getTaskId(), act.getProcInsId(), act.getComment(), act.getVars().getVariableMap());
		return "true";
	}
	
	/**
	 * 读取带跟踪的图片
	 */
	@RequestMapping(value = "trace/photo/{procDefId}/{execId}")
	public void tracePhoto(@PathVariable("procDefId") String procDefId, @PathVariable("execId") String execId, HttpServletResponse response) throws Exception {
		InputStream imageStream = actTaskService.tracePhoto(procDefId, execId);
		
		// 输出资源内容到相应对象
		byte[] b = new byte[1024];
		int len;
		while ((len = imageStream.read(b, 0, 1024)) != -1) {
			response.getOutputStream().write(b, 0, len);
		}
	}
	
	/**
	 * 输出跟踪流程信息
	 * 
	 * @param processInstanceId
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "trace/info/{proInsId}")
	public List<Map<String, Object>> traceInfo(@PathVariable("proInsId") String proInsId) throws Exception {
		List<Map<String, Object>> activityInfos = actTaskService.traceProcess(proInsId);
		return activityInfos;
	}

	/**
	 * 删除任务
	 * @param taskId 流程实例ID
	 * @param reason 删除原因
	 */
	@RequestMapping(value = "/deleteTask")
	public String deleteTask(String taskId, String reason) {
		String message = "";
		if (StringUtils.isBlank(reason)){
			message = "请填写删除原因";
		}else{
			actTaskService.deleteTask(taskId, reason);
			message = "删除任务成功，任务ID=" + taskId;
		}
		return message;
	}
	
	/* ===============================权限================================== */
	public Map<String, String> getHC(){
		Subject currentUser = SecurityUtils.getSubject();  //shiro管理的session
		Session session = currentUser.getSession();
		return (Map<String, String>)session.getAttribute(Const.SESSION_QX);
	}
	/* ===============================权限================================== */
	
	@InitBinder
	public void initBinder(WebDataBinder binder){
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(format,true));
	}
}
